package com.wugh.fast.security.social.config;

import com.wugh.fast.kernel.core.props.FastProperties;
import com.wugh.fast.kernel.core.props.SocialApplicationProperties;
import com.wugh.fast.kernel.core.props.SocialSecurityProperties;
import com.wugh.fast.security.social.app.qq.connet.QQConnectionFactory;
import com.wugh.fast.security.social.app.wechat.connect.WechatConnectionFactory;
import com.wugh.fast.security.social.view.ConnectStatusView;
import com.wugh.fast.security.social.view.ConnectView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.UserIdSource;
import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionSignUp;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.util.Assert;
import org.springframework.web.servlet.view.BeanNameViewResolver;

import javax.sql.DataSource;
import java.util.Objects;

/**
 * social配置的适配器
 * social配置,主要配置关系的存储方式
 */
@Slf4j
public class FastSocialConfigurerAdapter extends SocialConfigurerAdapter {
    @Autowired
    private DataSource dataSource;
    @Autowired
    private FastProperties fastProperties;
    @Autowired(required = false)
    private ConnectionSignUp connectionSignUp;

    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        //TODO 目前没有进行加密,后期需要加密存储
        JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
        SocialSecurityProperties social = fastProperties.getSecurity().getSocial();
        repository.setTablePrefix(social.getTablePrefix());
        if (Objects.equals(social.getAutoSignUp(), Boolean.TRUE) && connectionSignUp != null) {
            repository.setConnectionSignUp(connectionSignUp);
        }
        return repository;
    }

    @Override
    public UserIdSource getUserIdSource() {
        return () -> {
            SecurityContext context = SecurityContextHolder.getContext();
            Authentication authentication = context.getAuthentication();
            Assert.state(authentication != null, "Unable to get a ConnectionRepository: no user signed in");
            String userId;
            if (authentication.getPrincipal() instanceof SocialUserDetails) {
                userId = ((SocialUserDetails) authentication.getPrincipal()).getUserId();
            } else {
                userId = authentication.getName();
            }
            log.debug("系统-通用代码-获取当前用户ID:{}", userId);
            return userId;
        };
    }

    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) {

        SocialSecurityProperties social = fastProperties.getSecurity().getSocial();
        SocialApplicationProperties qq = social.getQq();
        if (qq != null) {
            connectionFactoryConfigurer.addConnectionFactory(new QQConnectionFactory(qq.getProviderId(), qq.getAppId(), qq.getAppSecret()));
        }
        SocialApplicationProperties wechat = social.getWechat();
        if (wechat != null) {
            connectionFactoryConfigurer.addConnectionFactory(new WechatConnectionFactory(wechat.getProviderId(), wechat.getAppId(), wechat.getAppSecret()));
        }
    }

    @Bean
    @ConditionalOnMissingBean
    public BeanNameViewResolver beanNameViewResolver() {
        BeanNameViewResolver viewResolver = new BeanNameViewResolver();
        viewResolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return viewResolver;
    }

    /**
     * 视图配置
     *
     * @return
     */
    @Bean({"connect/status"})
    public ConnectStatusView getConnectStatus() {
        return new ConnectStatusView();
    }

    @Bean({"connect/qqConnected", "connect/qqConnect", "connect/wechatConnected", "connect/wechatConnect"})
    public ConnectView getConnect() {
        return new ConnectView();
    }

}
